package com.xt.purchasingsystem.service.impl.productionManagementServiceImpl;

import com.xt.purchasingsystem.dto.*;
import com.xt.purchasingsystem.feign.PurchaseManagementClient;
import com.xt.purchasingsystem.mapper.*;
import com.xt.purchasingsystem.model.*;
import com.xt.purchasingsystem.service.productionManagementService.ProductPlanManagementService;
import com.xt.purchasingsystem.utils.PageBean;
import com.xt.purchasingsystem.utils.Result;
import com.xt.purchasingsystem.utils.ResultFactory;
import com.xt.purchasingsystem.utils.SerialNumberUtil;
import com.xt.purchasingsystem.vo.MApplyVo;
import com.xt.purchasingsystem.vo.MDesignProcedureDetailsVo;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author: 老姚
 * Date:  2020/4/19 11:07
 */
@Service
public class ProductPlanManagementServiceImpl implements ProductPlanManagementService {
    @Autowired
    private DFileMapper dFileMapper;
    @Autowired
    private MApplyMapper mApplyMapper;
    @Autowired
    private MDesignProcedureDetailsMapper mDesignProcedureDetailsMapper;
    @Autowired
    private MDesignProcedureModuleMapper mDesignProcedureModuleMapper;
    @Autowired
    private MManufactureMapper mManufactureMapper;
    @Autowired
    private MProcedureMapper mProcedureMapper;
    @Autowired
    private MProcedureModuleMapper mProcedureModuleMapper;
    @Autowired
    private SPayMapper sPayMapper;
    @Autowired
    private SPayDetailsMapper sPayDetailsMapper;
    @Autowired
    private SCellMapper sCellMapper;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Autowired
    private PurchaseManagementClient purchaseManagementClient;

    @Override
    public Result getAllPlanRegisterByPage(DFileDto dFileDto) {
        int rowCount = dFileMapper.rowCountByPlanRegister(dFileDto);
        PageBean pageBean = new PageBean(dFileDto.getPageSize(), dFileDto.getCurrNo(), rowCount);
        dFileDto.setCurrNo(pageBean.getStart());
        dFileDto.setPageSize(pageBean.getEnd());
        List<DFile> dFiles = dFileMapper.queryDFileByPlanRegister(dFileDto);
        pageBean.setPageList(dFiles);
        return ResultFactory.buildSuccessResult("查询成功", pageBean);
    }

    @Override
    @Transactional
    public Result submitProductPlans(List<MApply> mApplys) {
        for (MApply mApply : mApplys) {
            mApply.setApplyId(SerialNumberUtil.productPlanSerNumber());
            mApplyMapper.insert(mApply);
        }
        return ResultFactory.buildSuccessResult("提交成功,需要审核");
    }

    @Override
    public Result queryAllMApplyByUnreviewed(Integer currNo, Integer pageSize) {
        int rowCount = mApplyMapper.rowCountByUnreviewed();
        PageBean pageBean = new PageBean(pageSize, currNo, rowCount);
        List<MApply> allByUnreviewed = mApplyMapper.getAllByUnreviewed(pageBean.getStart(), pageBean.getEnd());
        pageBean.setPageList(allByUnreviewed);
        return ResultFactory.buildSuccessResult("查询成功", pageBean);
    }

    @Override
    @Transactional
    public Result auditMApply(MApply mApply) {
        int flag = mApplyMapper.updateByPrimaryKey(mApply);
        if (flag == 1) {
            return ResultFactory.buildSuccessResult("审核成功");

        } else {
            return ResultFactory.buildFailResult("审核失败");
        }
    }

    @Override
    public Result getAllMApplyByNotWork(MApplyDto mApplyDto) {
        int rowCount = mApplyMapper.rowCountByNotWork(mApplyDto);
        PageBean pageBean = new PageBean(mApplyDto.getPageSize(), mApplyDto.getCurrNo(), rowCount);
        mApplyDto.setCurrNo(pageBean.getStart());
        mApplyDto.setPageSize(pageBean.getEnd());
        List<MApplyVo> allByNotWork = mApplyMapper.getAllByNotWork(mApplyDto);
        pageBean.setPageList(allByNotWork);
        return ResultFactory.buildSuccessResult("查询成功", pageBean);
    }

    @Override
    @Transactional
    public Result getMDesignProcedureDetailsVos(String productId, Double amount) {
        List<MDesignProcedureDetailsVo> mDesignProcedureDetailsVos = new ArrayList<>();
        List<MDesignProcedureDetails> allMDesignProcedureDetailsByProductId = mDesignProcedureDetailsMapper.getAllMDesignProcedureDetailsByProductId(productId);
        for (MDesignProcedureDetails mDesignProcedureDetails : allMDesignProcedureDetailsByProductId) {
            mDesignProcedureDetails.setLabourHourAmount(BigDecimal.valueOf(mDesignProcedureDetails.getLabourHourAmount().doubleValue() * amount));
            mDesignProcedureDetails.setSubtotal(BigDecimal.valueOf(mDesignProcedureDetails.getSubtotal().doubleValue() * amount));
            mDesignProcedureDetails.setModuleSubtotal(BigDecimal.valueOf(mDesignProcedureDetails.getModuleSubtotal() == null ? 0 : mDesignProcedureDetails.getModuleSubtotal().doubleValue() * amount));

            List<MDesignProcedureModule> allByProcudureId = mDesignProcedureModuleMapper.getAllByProcudureId(mDesignProcedureDetails.getId());
            if (allByProcudureId != null && allByProcudureId.size() > 0) {
                for (MDesignProcedureModule mDesignProcedureModule : allByProcudureId) {
                    mDesignProcedureModule.setAmount(BigDecimal.valueOf(mDesignProcedureModule.getAmount().doubleValue() * amount));
                    mDesignProcedureModule.setSubtotal(BigDecimal.valueOf(mDesignProcedureModule.getSubtotal().doubleValue() * amount));
                }
            }
            MDesignProcedureDetailsVo mDesignProcedureDetailsVo = new MDesignProcedureDetailsVo(mDesignProcedureDetails, allByProcudureId);
            mDesignProcedureDetailsVos.add(mDesignProcedureDetailsVo);
        }
        return ResultFactory.buildSuccessResult("查询成功", mDesignProcedureDetailsVos);
    }

    @Override
    @Transactional
    public Result submitProductionOrder(ProductionOrderDto productionOrderDto) {
        List<Integer> list = new ArrayList<>();
        String[] split = {};
        if (productionOrderDto.getMmanufacture().getApplyIdGroup().length() > 1) {
            split = productionOrderDto.getMmanufacture().getApplyIdGroup().split("\\|");
            for (String s : split) {
                list.add(Integer.parseInt(s));
            }
        } else {
            list.add(Integer.parseInt(productionOrderDto.getMmanufacture().getApplyIdGroup()));
        }
        productionOrderDto.getMmanufacture().setManufactureId(SerialNumberUtil.orderNumber());
        mManufactureMapper.insert(productionOrderDto.getMmanufacture());
        Integer id = productionOrderDto.getMmanufacture().getId();

        for (MProcedureAndModuleDto mprocedureAndModuleDto : productionOrderDto.getMprocedureAndModuleDtos()) {
            mprocedureAndModuleDto.getMprocedure().setParentId(id);
            mProcedureMapper.insert(mprocedureAndModuleDto.getMprocedure());
            if (mprocedureAndModuleDto.getMprocedureModules() != null && mprocedureAndModuleDto.getMprocedureModules().size() > 0) {
                for (MProcedureModule mprocedureModule : mprocedureAndModuleDto.getMprocedureModules()) {
                    mprocedureModule.setParentId(mprocedureAndModuleDto.getMprocedure().getId());
                    mProcedureModuleMapper.insert(mprocedureModule);
                }
            }
        }
        for (Integer idd : list) {
            mApplyMapper.dispatche(idd);
        }
        return ResultFactory.buildSuccessResult("提交成功,需要审核");
    }

    @Override
    public Result getAllUnreviewedByPage(Integer currNo, Integer pageSize) {
        List<ProductionOrderDto> list = new ArrayList<>();
        int rowCount = mManufactureMapper.rowCountByUnreviewed();
        PageBean pageBean = new PageBean(pageSize, currNo, rowCount);
        List<MManufacture> allByUnreviewed = mManufactureMapper.getAllByUnreviewed(pageBean.getStart(), pageBean.getEnd());
        pageBean.setPageList(allByUnreviewed);
        return ResultFactory.buildSuccessResult("查询成功", pageBean);

    }

    @Override
    public Result getAllMProcedureAndModulesById(Integer id) {
        List<MProcedureAndModuleDto> mprocedureAndModuleDtos = new ArrayList<>();
        List<MProcedure> allByParentId = mProcedureMapper.getAllByParentId(id);
        if (allByParentId != null && allByParentId.size() > 0) {
            for (MProcedure mProcedure : allByParentId) {
                MProcedureAndModuleDto mProcedureAndModuleDto = new MProcedureAndModuleDto();
                List<MProcedureModule> allByParentId1 = mProcedureModuleMapper.getAllByParentId(mProcedure.getId());
                mProcedureAndModuleDto.setMprocedure(mProcedure);
                mProcedureAndModuleDto.setMprocedureModules(allByParentId1);
                mprocedureAndModuleDtos.add(mProcedureAndModuleDto);
            }
        }
        return ResultFactory.buildSuccessResult("查询成功", mprocedureAndModuleDtos);
    }

    @GlobalTransactional
    @Override
    public Result reviewProductionDispatchOrder(ProductionOrderDto productionOrderDto) {
        if ("S001-1".equals(productionOrderDto.getMmanufacture().getCheckTag())) {
            for (MProcedureAndModuleDto mprocedureAndModuleDto : productionOrderDto.getMprocedureAndModuleDtos()) {
                if (mprocedureAndModuleDto.getMprocedureModules() != null && mprocedureAndModuleDto.getMprocedureModules().size() > 0) {
                    SPay sPay = new SPay();
                    String orderSerNumber = SerialNumberUtil.outOrderSerNumber();
                    sPay.setPayId(orderSerNumber);
                    sPay.setReason("C002-1");
                    String reasonexact = productionOrderDto.getMmanufacture().getManufactureId() + "-" + mprocedureAndModuleDto.getMprocedure().getProcedureName();

                    sPay.setReasonexact(reasonexact);
                    sPay.setCostPriceSum(mprocedureAndModuleDto.getMprocedure().getModuleSubtotal());
                    double amountSum = 0;
                    for (MProcedureModule mprocedureModule : mprocedureAndModuleDto.getMprocedureModules()) {
                        amountSum += mprocedureModule.getAmount().doubleValue();
                    }
                    sPay.setAmountSum(BigDecimal.valueOf(amountSum));
                    sPay.setRegister(productionOrderDto.getMmanufacture().getChecker());
                    sPay.setRegisterTime(productionOrderDto.getMmanufacture().getCheckTime());
                    sPay.setCheckTag("S001-1");
                    sPay.setStoreTag("K002-1");
                    sPayMapper.insert(sPay);

                    List<OutboundProcurementDetail> outboundProcurementDetails = new ArrayList<>();
                    double purchaseSummoney = 0;
                    for (MProcedureModule mprocedureModule : mprocedureAndModuleDto.getMprocedureModules()) {
                        SCell byProductId = sCellMapper.getByProductId(mprocedureModule.getProductId());

                        if (byProductId != null) {
                            if (byProductId.getAmount().doubleValue() < mprocedureModule.getAmount().doubleValue()) {
                                OutboundProcurementDetail outboundProcurementDetail = new OutboundProcurementDetail();
                                outboundProcurementDetail.setProductId(mprocedureModule.getProductId());
                                outboundProcurementDetail.setProductName(mprocedureModule.getProductName());
                                outboundProcurementDetail.setOutboundAmount(mprocedureModule.getAmount().doubleValue());
                                outboundProcurementDetail.setQuantityStock(byProductId.getAmount().doubleValue());
                                outboundProcurementDetail.setPurchaseAmount(mprocedureModule.getAmount().doubleValue() - byProductId.getAmount().doubleValue());
                                outboundProcurementDetail.setPrice(mprocedureModule.getCostPrice().doubleValue());
                                purchaseSummoney += (mprocedureModule.getAmount().doubleValue() - byProductId.getAmount().doubleValue()) * mprocedureModule.getCostPrice().doubleValue();
                                outboundProcurementDetails.add(outboundProcurementDetail);
                            }
                        } else {
                            OutboundProcurementDetail outboundProcurementDetail = new OutboundProcurementDetail();
                            outboundProcurementDetail.setProductId(mprocedureModule.getProductId());
                            outboundProcurementDetail.setProductName(mprocedureModule.getProductName());
                            outboundProcurementDetail.setOutboundAmount(mprocedureModule.getAmount().doubleValue());
                            outboundProcurementDetail.setPurchaseAmount(mprocedureModule.getAmount().doubleValue());
                            purchaseSummoney += mprocedureModule.getAmount().doubleValue() * mprocedureModule.getCostPrice().doubleValue();
                            outboundProcurementDetail.setPrice(mprocedureModule.getCostPrice().doubleValue());
                            outboundProcurementDetails.add(outboundProcurementDetail);
                        }

                        SPayDetails sPayDetails = new SPayDetails();
                        sPayDetails.setParentId(sPay.getId());
                        sPayDetails.setProductId(mprocedureModule.getProductId());
                        sPayDetails.setProductName(mprocedureModule.getProductName());
                        sPayDetails.setAmount(mprocedureModule.getAmount());
                        sPayDetails.setCostPrice(mprocedureModule.getCostPrice());
                        sPayDetails.setSubtotal(mprocedureModule.getSubtotal());
                        sPayDetails.setPayTag("K002-1");
                        sPayDetailsMapper.insert(sPayDetails);
                    }

                    if (outboundProcurementDetails.size() > 0) {
                        OutboundProcurement outboundProcurement = new OutboundProcurement();
                        outboundProcurement.setPayId(orderSerNumber);
                        outboundProcurement.setReason("C002-1");
                        outboundProcurement.setReasonexact(reasonexact);
                        outboundProcurement.setRegisterTime(productionOrderDto.getMmanufacture().getCheckTime());
                        outboundProcurement.setOutboundSumamount(amountSum);
                        outboundProcurement.setCostPriceSum(mprocedureAndModuleDto.getMprocedure().getModuleSubtotal().doubleValue());
                        outboundProcurement.setPurchaseTag("P001-0");
                        outboundProcurement.setPurchaseSummoney(purchaseSummoney);
                        double purchaseSumamount = 0;

                        for (OutboundProcurementDetail outboundProcurementDetail : outboundProcurementDetails) {
                            purchaseSumamount += outboundProcurementDetail.getPurchaseAmount();
                        }
                        outboundProcurement.setPurchaseSumamount(purchaseSumamount);

                        OutboundProcurementDto outboundProcurementDto = new OutboundProcurementDto();
                        outboundProcurementDto.setOutboundProcurement(outboundProcurement);
                        outboundProcurementDto.setOutboundProcurementDetails(outboundProcurementDetails);
                        CompletableFuture.runAsync(() -> {
                            purchaseManagementClient.saveOutboundProcurement(outboundProcurementDto);
                        }, threadPoolExecutor);
                    }

                }
            }
        }

        mManufactureMapper.updateByPrimaryKey(productionOrderDto.getMmanufacture());
        return ResultFactory.buildSuccessResult("审核成功");

    }

}
